// Copyright (c) Microsoft Corporation. All rights reserved.

namespace SPPivotViewer.HttpHandler.Internal
{
    using System;
    using System.Collections.Specialized;
    using System.Collections.Generic;
    using Microsoft.SharePoint;
    using System.Xml;
    using System.Web;
    using System.IO;
    using System.Text.RegularExpressions;
    using SPPivotViewer.Utility;





    /// <summary>
    /// Your collection factory must derive from this class.
    /// Derived instances will be detected and loaded automatically,
    ///   so must have a public constructor that takes no parameters.
    /// </summary>
    public class SPListCollectionFactory
    {
        // Constructors, Finalizer and Dispose
        //======================================================================

        public SPListCollectionFactory()
        {
        }


        // Public Properties
        //======================================================================

        /// <summary>
        /// The filebody used in the URL to refer to this collection.
        /// If null, the classname is used.
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// A summary of the collection, including URL query parameters that it accepts.
        /// </summary>
        public string Summary { get; set; }


        private SPListCollectionParam _param;
        // Public Methods
        //======================================================================

        /// <summary>
        /// Override this method to provide a Collection object for the request.
        /// </summary>
        public Collection MakeCollection(CollectionRequestContext context, string collectionFileName, SPListCollectionParam param)
        {
            _param = param;
            string strImageField = param.ImageField;
            string strImageSubstitue = param.ImageSubstitue;
            string strFieldUrl = param.FieldUrl;

            Collection col = new Collection();
            col.Name = collectionFileName;
            SPWeb oWeb = SPContext.Current.Web;
            
                SPList oList = oWeb.Lists[collectionFileName];
                SPQuery query = new SPQuery();
                string strMaxItem = PV4SPSettings.GetValue(SPContext.Current.Web, PV4SPSettings.cstMaxItem);
                uint _iMaxItem = 0;
                query.RowLimit = uint.TryParse(strMaxItem, out _iMaxItem) ? _iMaxItem : 300; 
                SPListItemCollection oLIC = oList.GetItems(query);
                //SPListItemCollection oLIC = oList.Items;
                foreach (SPListItem item in oLIC)
                {
                    
                    List<Facet> lstFacet = CreateFacet(item);
                    string strName = String.IsNullOrEmpty(item.Title) ? String.IsNullOrEmpty(item.Name) ? "No title" : item.Name : item.Title;
                    string fullURL = item["ows_EncodedAbsUrl"].ToString();
                    string docUrl = "";
                    if (string.IsNullOrEmpty(strFieldUrl))
                    {
                        docUrl = fullURL;
                    }
                    else
                    {
                        if (item.Fields.ContainsField(strFieldUrl) && item[strFieldUrl] != null)
                        {
                            docUrl = item[strFieldUrl].ToString();
                        }
                    }
                    ItemImage img = null;
                    if (!string.IsNullOrEmpty(strImageField) && (strImageField == "Item Url" || item.Fields.ContainsField(strImageField)))
                    {
                        if (strImageField == "Item Url")
                        {
                            string strFileExt = getFileExtension(new Uri(fullURL));
                            if (IsImageFormatSupport(strFileExt.ToLower()))
                                img = new ItemImage(new Uri(fullURL));
                        }
                        else if (item[strImageField] != null)
                        {
                            SPFieldUrlValue urlFieldValue = new SPFieldUrlValue(item[strImageField].ToString());
                            string strImageurl = urlFieldValue.Url;
                            string strFileExt = getFileExtension(new Uri(strImageurl));
                            if (IsImageFormatSupport(strFileExt.ToLower()))
                                img = new ItemImage(new Uri(strImageurl));
                        }
                        if (img == null && !string.IsNullOrEmpty(strImageSubstitue))
                        {

                            string strFileExt = getFileExtension(new Uri(strImageSubstitue));
                            if (IsImageFormatSupport(strFileExt.ToLower()))
                                img = new ItemImage(new Uri(strImageSubstitue));
                        }

                    }
                    else
                    {
                        img = new ItemImage(new Uri(fullURL));  
                    }
                    col.AddItem(strName, docUrl, null, img, lstFacet.ToArray());

                }
                return col;
            
        }

        private bool IsImageFormatSupport(string ext)
        {
            List<string> lstStr=new List<string>();
            lstStr.Add("bmp");
            lstStr.Add("jpg");
            lstStr.Add("jpeg");
            lstStr.Add("png");
            lstStr.Add("wmf");
            lstStr.Add("gif");
            lstStr.Add("ico");
            lstStr.Add("tiff");
            lstStr.Add("tif");

            return lstStr.Contains(ext);
        }
        private string getFileExtension(Uri url)
        {
            string strFileExt = "";
            string strFileUrl = url.AbsolutePath;
            strFileExt = strFileUrl.Substring(url.AbsolutePath.LastIndexOf('.') + 1);
            return strFileExt.Trim();
        }
        private List<Facet> CreateFacet(SPListItem item)
        {
            List<Facet> lstReturn = new List<Facet>();
            List<string> lstFacet = new List<string>();
            List<string> lstInfos = new List<string>();
            if (_param.Facets != null)
                lstFacet.AddRange(_param.Facets);
            if (_param.Infos != null)
                lstInfos.AddRange(_param.Infos);
            foreach (SPField fld in item.ParentList.Fields)
            {
                if (!(fld.InternalName == "File_x0020_Type" || fld.InternalName == "ContentType" || (fld.Type == SPFieldType.Computed && fld.InternalName == "FileSizeDisplay")))
                    if (fld.Hidden)
                        continue;
                if ((!lstFacet.Contains(fld.Title) && lstFacet.Count > 0) && (!lstInfos.Contains(fld.Title) && lstInfos.Count > 0))
                    continue;
                if (!item.Fields.ContainsField(fld.StaticName) || item[fld.Id] == null)
                    continue;
                FacetType typeFacet;
                object valueFacet = null;
                if (!getFacetTypeFromField(fld, out typeFacet))
                    continue;
                if (fld.InternalName == "ContentType")
                    typeFacet = FacetType.Text;
                if (!getValueFromItem(item, fld, typeFacet, out valueFacet))
                    continue;
                if (valueFacet == null)
                    continue;
                string strFacetName = fld.Title;
                if (strFacetName.ToLower() == "name" || strFacetName.ToLower() == "description")
                    strFacetName = "[" + strFacetName + "]";
                Facet facet = new Facet(strFacetName, typeFacet, valueFacet);

                if (typeFacet == FacetType.Link)
                    facet.ShowInFacetPane = false;

                if (lstFacet.Count > 0 && !lstFacet.Contains(fld.Title))
                    facet.ShowInFacetPane = false;
                if (lstInfos.Count > 0 && !lstInfos.Contains(fld.Title))
                    facet.ShowInInfoPane = false;

                lstReturn.Add(facet);


            }
            string ItemDispFormUrl = String.Concat(item.Web.Url, "/", item.ParentList.Forms[PAGETYPE.PAGE_DISPLAYFORM].Url, "?id=", item.ID.ToString());

            Facet fctID = new Facet("Item DispPage", ItemDispFormUrl);
            fctID.ShowInFacetPane = false;
            fctID.ShowInInfoPane = false;
            lstReturn.Add(fctID);
            return lstReturn;

        }

        private bool getValueFromItem(SPListItem item, SPField fld, FacetType typeFacet, out object valueFacet)
        {
            valueFacet = null;
            if (typeFacet == FacetType.DateTime)
            {
                return getFacetValueToDate(item, fld, out  valueFacet);
            }
            if (typeFacet == FacetType.Text)
            {
                return getFacetValueToText(item, fld, out  valueFacet);
            }
            if (typeFacet == FacetType.Link)
            {
                return getFacetValueToLink(item, fld, out  valueFacet);
            }
            if (typeFacet == FacetType.Number)
            {
                return getFacetValueToNumber(item, fld, out  valueFacet);
            }
            return false;
        }

        private bool getFacetValueToNumber(SPListItem item, SPField fld, out object valueFacet)
        {
            valueFacet = null;
            if (item[fld.Id] == null)
                return false;
            int iValue;
            bool biValue = int.TryParse(item[fld.Id].ToString(), out iValue);

            float fValue;
            bool bfValue = float.TryParse(item[fld.Id].ToString(), out fValue);

            if (!bfValue && !biValue)
                return false;


            if (fValue == iValue)
                valueFacet = iValue;
            else
                valueFacet = fValue;
            return true;
        }

        private bool getFacetValueToLink(SPListItem item, SPField fld, out object valueFacet)
        {
            valueFacet = null;
            //return false;
            if (item[fld.Id] == null)
                return false;
            SPFieldUrlValue lkValue = new SPFieldUrlValue(item[fld.Id].ToString());
            if (lkValue == null)
                return false;

            FacetHyperlink fh = new FacetHyperlink(lkValue.Description, lkValue.Url);
            if (fh.Name == null || fh.Url == null)
                return false;
            valueFacet = fh;
            return true;
        }

        private bool getFacetValueToText(SPListItem item, SPField fld, out object valueFacet)
        {
            valueFacet = null;
            if (item[fld.Id] == null)
                return false;
            if (fld.Type == SPFieldType.User)
                valueFacet = new SPFieldUserValue(item.Web, item[fld.Id].ToString()).LookupValue;
            else
                valueFacet = item[fld.Id].ToString();
            if (valueFacet.ToString() == string.Empty)
                return false;
            else
                return true;
        }

        private bool getFacetValueToDate(SPListItem item, SPField fld, out object valueFacet)
        {
            valueFacet = null;
            if (item[fld.Id] == null)
                return false;
            DateTime? dtValue = item[fld.Id] as DateTime?;
            if (dtValue == null || !dtValue.HasValue)
                return false;
            valueFacet = dtValue.Value;
            return true;

        }

        private bool getFacetTypeFromField(SPField fld, out FacetType outFacet)
        {
            outFacet = FacetType.Text;
            bool bReturn = false;
            if (fld.Type == SPFieldType.AllDayEvent || fld.Type == SPFieldType.DateTime)
            {
                outFacet = FacetType.DateTime;
                bReturn = true;
            }
            if (fld.Type == SPFieldType.Text || fld.Type == SPFieldType.Choice || fld.Type == SPFieldType.MultiChoice || fld.Type == SPFieldType.Note || fld.Type == SPFieldType.User)
            {
                outFacet = FacetType.Text;
                bReturn = true;
            }
            if (fld.Type == SPFieldType.URL)
            {
                outFacet = FacetType.Link;
                bReturn = true;
            }
            if (fld.Type == SPFieldType.Currency || fld.Type == SPFieldType.Integer || fld.Type == SPFieldType.Number || fld.Type == SPFieldType.Computed)
            {
                outFacet = FacetType.Number;
                bReturn = true;
            }

            return bReturn;
        }
    }

}
